package com.exe.rege.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.exe.rege.common.CustomException;
import com.exe.rege.dto.DishDto;
import com.exe.rege.entity.CategoryEntity;
import com.exe.rege.entity.DishEntity;
import com.exe.rege.entity.DishFlavorEntity;
import com.exe.rege.entity.SetmealDishEntity;
import com.exe.rege.mapper.DishFlavorMapper;
import com.exe.rege.mapper.DishMapper;
import com.exe.rege.service.CategoryService;
import com.exe.rege.service.DishFlavorService;
import com.exe.rege.service.DishService;
import com.exe.rege.service.SetmealDishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DishServiceImpl extends ServiceImpl<DishMapper, DishEntity> implements DishService {
    @Autowired
    private DishService dishService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Override
    @Transactional//因为对多张表有操作，加入事务控制的注解
    public void saveWithFlavor(DishDto dishDto) {
        //保存菜品的基本信息
        this.save(dishDto);

        //保存菜品的口味信息
        //直接这样会漏掉菜品的id所以需要先获取id，再遍历写入口味表
//        dishFlavorService.saveBatch(dishDto.getFlavors());
        Long dishId = dishDto.getId();
        //菜品口味
        List<DishFlavorEntity> flavors = dishDto.getFlavors();

        //遍历写入
        flavors = flavors.stream().map(it -> {
            it.setDishId(dishId);
            return it;
        }).collect(Collectors.toList());

        //保存
        dishFlavorService.saveBatch(flavors);

    }

    /**
     * 根据id查询菜品信息和对应的口味信息
     * @param id
     * @return
     */
    @Override
    @Transactional
    public DishDto getByIdWithFlavor(Long id) {
        //查询菜品基本信息，通过id
        DishEntity dishEntity = this.getById(id);

        //将基础信息拷贝到dto里
        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(dishEntity, dishDto);

        //查询当前菜品对应的口味信息，从dish_flavor表查询
        LambdaQueryWrapper<DishFlavorEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavorEntity::getDishId, id);
        List<DishFlavorEntity> list = dishFlavorService.list(queryWrapper);
        dishDto.setFlavors(list);

        return dishDto;
    }

    @Override
    public void updateWithFlavor(DishDto dishDto) {
        //更新dish表
        this.updateById(dishDto);

        //更新dish_flavor表：因为这相当于一个中间表，即拥有两个表的数据，修改并不知道是全改还是改部分
        //方便的方法是全删了重新添加，如果表特别大，修改少量数据会有点浪费，但是目前这个情况还是先删后改
        //delete dish_flavor 清理当前菜品对应的口味数据
        LambdaQueryWrapper<DishFlavorEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavorEntity::getDishId, dishDto.getId());
        dishFlavorService.remove(queryWrapper);

        //save dish_flavor 添加当前提交过来的口味参数，注意此时传过来的口味信息还是会漏掉菜品id
        //先获取菜品id
        Long dishId = dishDto.getId();
        //再获取口味信息
        List<DishFlavorEntity> flavors = dishDto.getFlavors();

        //处理口味信息，将id遍历赋值进口味信息里
        List<DishFlavorEntity> flavorEntityList = flavors.stream().map(it -> {
            it.setDishId(dishId);
            return it;
        }).collect(Collectors.toList());

        //保存
        dishFlavorService.saveBatch(flavorEntityList);
    }

    @Override
    public Page<DishDto> getPage(int page, int pageSize, String name) {
        //构造分页构造器对象
        Page<DishEntity> pageInfo = new Page<>(page,pageSize);
        //仅仅是菜品还不够，页面有菜品图片和分类名称，故还要加上这个对象
        Page<DishDto> dishDtoPage = new Page<>();

        //条件构造器，先查菜品
        LambdaQueryWrapper<DishEntity> queryWrapper = new LambdaQueryWrapper<>();
        //添加过滤条件
        queryWrapper.like(name != null, DishEntity::getName, name);
        //添加排序条件
        queryWrapper.orderByDesc(DishEntity::getUpdateTime);
        //执行分页查询
        dishService.page(pageInfo, queryWrapper);

        //菜品查好后，将已获取的基础属性全部拷贝到dto里，暂时不拷贝records，因为这里面具体内容还需要处理
        BeanUtils.copyProperties(pageInfo, dishDtoPage, "records");

        //取出records，准备处理
        List<DishEntity> records = pageInfo.getRecords();

        //将records 里的id取出来，查到对应的分类名，再返回
        List<DishDto> dishDtoList = records.stream().map(it ->{
            //新建一个dto对象
            DishDto dishDto = new DishDto();

            //拷贝进新的对象里
            BeanUtils.copyProperties(it, dishDto);

            //获取分类id
            Long categoryId = it.getCategoryId();

            //通过id查询分类对象
            CategoryEntity categoryEntity = categoryService.getById(categoryId);

            //获取分类名
            if (categoryEntity != null){
                String categoryEntityName = categoryEntity.getName();
                dishDto.setCategoryName(categoryEntityName);
            }
            return dishDto;
        }).collect(Collectors.toList());

        dishDtoPage.setRecords(dishDtoList);

        return dishDtoPage;
    }

    /**
     * 删除菜品时，与套餐有关联的不能直接删
     * @param ids
     * @return
     */
    @Override
    public void deleteByIds(String ids) {
        //将传来的字符串分割成单个id
        String[] split = ids.split(",");
        //每个id还是字符串，转成Long
        List<Long> idList = Arrays.stream(split)
                .map(it -> Long.parseLong(it.trim()))
                .collect(Collectors.toList());

        //没有套餐关联，则跟着将菜品口味表和菜品表一起删除
        for (Long id : idList){
            //查询当前要删除的菜品是否和套餐有关联
            LambdaQueryWrapper<SetmealDishEntity> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SetmealDishEntity::getDishId, id);
            int count = setmealDishService.count(queryWrapper);
            //查套餐里面对应id个数，大于0则有关联的
            if (count > 0){
                throw new CustomException("本菜品已有套餐使用，不能直接删除。");
            }

            //查询当前要删除的菜品是否和菜品口味表关联
            LambdaQueryWrapper<DishFlavorEntity> flavorQueryWrapper = new LambdaQueryWrapper<>();
            //将关联的删掉
            flavorQueryWrapper.eq(DishFlavorEntity::getDishId, id);
            dishFlavorService.remove(flavorQueryWrapper);

            this.removeById(id);
        }
    }

    @Override
    public void updateStatus(Integer status, String ids) {
        //将传来的ids分割为一条条id
        String[] split = ids.split(",");
        //将分好的一条条传入成List<Long>
        List<Long> idList = Arrays.stream(split)
                .map(it -> Long.parseLong(it.trim()))
                .collect(Collectors.toList());
        //给每个id new一个dishEntity对象，将状态遍历set进去
        List<DishEntity> newDish = idList.stream().map(it -> {
            DishEntity dishEntity = new DishEntity();
            dishEntity.setId(it);
            dishEntity.setStatus(status);
            return dishEntity;
        }).collect(Collectors.toList());

        //批量修改
        dishService.updateBatchById(newDish);
    }
}
